﻿using mozhi.smarterp.Finance.Basedatas.Repository;
using mozhi.smarterp.Finance.Files;
using mozhi.smarterp.Finance.Files.Services;
using Mozhi.Abp.Core.Offices;
using Mozhi.Abp.Core.Offices.Words;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp;

namespace mozhi.smarterp.Finance.Ieps.Print
{
    public class PrintHandlerBase<TData> : IPrintHandler
    {
        protected IServiceProvider _serviceProvider;

        protected FileManager _fileManager;

        protected List<TData> _datas;

        protected IPrintTemplateRepository _templateRepository;

        protected PrintQueryDto _query;

        public PrintHandlerBase(IServiceProvider serviceProvider)
        {
            _serviceProvider = serviceProvider;
            _fileManager = _serviceProvider.GetService(typeof(FileManager)) as FileManager;
            _templateRepository = _serviceProvider.GetService(typeof(IPrintTemplateRepository)) as IPrintTemplateRepository;
        }

        public async Task<Files.File> GetPrintFileAsync(PrintQueryDto query)
        {
            _query = query;

            _datas = await GetDataAsync(query);

            if (_datas == null || _datas.Count == 0)
                throw new UserFriendlyException("没有需要打印的数据", "100000");

            var printDatas = GetPrintDatas();


            var printOption = GetPrintOption();

            var wordHandler = WordHandlerFacotry.Instance("spire");

            var templateStream = await GetTemplateStreamAsync(query);

            var stream = wordHandler.GetPrintFileStream(templateStream, printDatas, printOption);

            var contentType = printOption.FileType == FileType.PDF ? "application/pdf" : "application/vnd.openxmlformats-officedocument.wordprocessingml.template";

            var file = await _fileManager.CreateAsync(GetFileName(), contentType, stream);

            return file;

        }


        protected virtual async Task<List<TData>> GetDataAsync(PrintQueryDto query)
        {
            return default(List<TData>);
        }


        protected virtual List<PrintData> GetPrintDatas()
        {
            return new List<PrintData>();
        }

        protected virtual PrintOption GetPrintOption()
        {
            return new PrintOption() { FileType = FileType.PDF };
        }


        protected virtual string GetFileName()
        {
            var moduleName = GetModuleName(_query.ModuleCode);

            var fileNameSuffix = DateTime.Now.ToString("yyyyMMddHHmmss");

            var fileName = moduleName.IsNullOrEmpty() ? fileNameSuffix : $"{moduleName}_{fileNameSuffix}";

            var printOption = GetPrintOption();

            var fileExtension = printOption.FileType == FileType.PDF ? ".PDF" : ".DOCX";


            return fileName + fileExtension;
        }

        #region
        private async Task<Stream> GetTemplateStreamAsync(PrintQueryDto query)
        {
            if (query.TemplateId == default)
                throw new UserFriendlyException("请选择打印模板", "100000");

            var printTemplate = await _templateRepository.GetAsync(query.TemplateId);

            if(printTemplate==null)
                throw new UserFriendlyException($"打印模板：{query.TemplateId}不存在", "100000");

            var fileResult = await _fileManager.DownloadFileAsync(printTemplate.TemplateFileId);

            if (fileResult == null)
                throw new UserFriendlyException($"打印模板：{query.TemplateId}不存在", "100000");

            var templateStream = fileResult.Item1;

            return templateStream;
        }

        protected virtual string GetModuleName(string code)
        {
            if (code == "journal")
                return "凭证";

            return "";
        }
        #endregion
    }
}
